Drag-and-Drop Inventory Sample$
This sample (INVENT) provides a practical illustration of how to implement effective drag-and-drop with database applications.
More information is available on the following topics:
How to Operate INVENT
How INVENT was written
Custom controls used by INVENT
Setting up INVENT should be pretty easy.  Placing all of the files in a single directory, then running Visual Basic (in design-mode) to open INVENT.MAK.  If you press the run button (or use F5) you should be able to use INVENT with no problems.
Here are some of the features illustrated by the application:
1.	Drag-and-drop reduces the complexity of the user interface.  Creating orders is as simple as dragging a customer into an order table.  To edit an order, you drag it to an empty spot on the main MDI form.  Parts can be dropped right into the line items grid.  Accomplishing the same tasks with the keyboard or menus can be complex and time consuming by comparison.
2.	INVENT makes extensive use of Access database features found in Visual Basic 3.0.  A single inventory database contains tables for customers, parts, and the orders themselves.  The application contains features for creating your own customer tables, part tables, and order browsers.  All of the information is stored in a single Access database which describes the “world” of the inventory user.
3.	Implementing grid drag and drop is often difficult.  INVENT uses Apex’s TrueGrid (a demo copy is included) to illustrate how rows can be dragged from one grid to another and records can be added just by dropping.  INVENT uses the drag-drop protocols used in the APPTBOOK sample application described in the Apr/May ‘92 BasicPro article Drag Until You Drop.  These protocols allow you to easily define where items may be dropped and how.
4.	INVENT recognizes files dropped from the Windows Program manager.  If an inventory file is dropped into the main MDI form, it is automatically opened.  Multiple files may be dropped.  This is accomplished using the DRAGDROP.VBX control.  This control was written by Gary Wisniewski (VBITS presenter for INVENT) and can be freely distributed and used at no charge.  Documentation and samples for DRAGDROP.VBX are available in the CompuServe MSBASIC forum in Library 5 (Visual Basic/Windows).

How INVENT Was Written#$
Invent is pretty complex, so this won’t be a tutorial, but will serve as a guide to the modules present in INVENT and some techniques which were used.
Overview of Techniques
Everyone has their own way of using Visual Basic.  INVENT was written by someone who uses C and C++ most of the time.  Some “bad habits” may have made their way into the pristine world of Visual Basic.  So, if you find something you don’t like ... you can improve on it!
Here are some of the techniques you should look for when browsing the INVENT source code:
1.	Centralized Form Management.  A single module, FORMMGR, is used to manage instances of each form and to maintain the form lists.  Since you can open many customer forms, parts forms, order browsers, and order forms, it was useful to develop a single set of techniques for maintaining all of these lists.
2.	.FRM/.BAS Pairing.  For each .FRM file, there is a corresponding .BAS file with the same name.  The .BAS file contains routines which need to be accessed globally to control the .FRM file with the same name.  For example, the routine PartsOpen is in PARTS.BAS.  It creates an instance of a PARTS.FRM and loads it with the appropriate parts list.  The .BAS file contains initialization for the form lists.  All the initialization routines are called from Sub Main.
3.	Database Table Definitions.  INVENT is used to create its own databases, so it needs complete information about the field layouts (we call it the schema) for the database.  In PARTS.BAS, OBROWSE.BAS, and CUST.BAS you will find initialization routines which set up an array containing field definition information.  Routines in DBS.BAS are then used to create each table when necessary.
4.	Bound Controls.  INVENT uses Visual Basic bound text controls, and a bound grid control (TrueGrid) to accomplish all of its work.  Each control is bound to a local data control on the form.  Since you can’t reference data controls across forms, each form opens the database itself.  Thus each form is independent once it is created.
5.	TrueGrid Control.  INVENT relies heavily on TrueGrid (our product) to perform all table displays as well as displaying the list of tables in the database (using its unbound mode).  To some extent, we included this to entice you into liking TrueGrid (of course).  However, for the most part we have done this to illustrate important techniques which are frequently encountered in database applications.  The demo version of TrueGrid which is included allows you to experiment with INVENT and modify it for your own enjoyment.
Module Descriptions
CUST.FRM	This form contains the customer browser form.  It is opened by dragging a customer table from the database table browser (DBSFORM.FRM).
DBSFORM.FRM	This contains an unbound TrueGrid which is used to display the tables in the database.  System tables are automatically ignored.
MAINMDI.FRM	The main MDI form contains the status bar, and the DRAGDROP.VBX control which is used for file manager drag and drop.  Its DragDrop handler opens tables and orders automatically.
NEWFORM.FRM	This is a small form which is used to respond to the Table...New menu item.
OBROWSE.FRM	This displays an order browser.  The RowChange event in this browser saves the order number so it can be used by the order form when it opens.  When you reactivate this form, it refreshes the current row in case an item has been updated.
ORDER.FRM	This is the main order form, containing line items and an item header.  It contains two data controls with different RecordSource properties.  One selects only the header, and the other selects the detail lines.  This is done by performing an SQL query using the IsDetail field value.
PARTS.FRM	The parts form allows you to browse parts.  Like other forms, the down arrow adds a new order by adding one to the last order number in the table.
UTILS.FRM	This form isn’t really displayed.  It is used as a holding place for icons and bitmaps which are used elsewhere.
CUST.BAS	This module contains public routines needed to manipulate customer tables and initialize them.
DBS.BAS	This module contains routines used for creating new tables, deleting tables, and managing the list of tables displayed by the DBSFORM.FRM module.
DRAG.BAS	This contains the protocols for managing drag and drop.  This module is almost identical to the module used by the APPTBOOK sample.
FORMMGR.BAS	This module contains generic routines for maintaining lists of form instances.
INVENT.BAS	Contains global constant and variable definitions, as well as Sub Main and a few utility routines which are application related.
OBROWSE.BAS	This module contains public routines needed to manipulate lists of orders and initialize them.
ORDER.BAS	This module contains public routines needed to open and initialize orders.
PARTS.BAS	This module contains public routines needed to open and initialize parts lists.
UTILS.BAS	Contains generic utility routines needed for working with the common dialogs, and for extracting file names and paths from strings.
There’s always more to do ...
Although INVENT contains lots of features, and almost appears to be ready-to-use, there is actually a lot to do if you want to make it into a full-fledged application.  The sample is intended to illustrate how drag-and-drop can be used effectively, rather than delving deeply into many of the database issues.
Here are some things you might consider if you want to make INVENT more robust:
1.	Consistency checking.  INVENT doesn’t care if you delete customers who have orders, or whether you delete orders which are currently being filled out.  A finished application would prevent the user from doing anything harmful to their data.
2.	Context sensitive help.  Each control within a form should have context sensitive help.
3.	Concurrency control.  INVENT is a multi-user application by definition.   You can open two copies of the same order and work with them simultaneously.  INVENT requires work in order to be aware of what other network users are doing, and what is going on when multiple copies of the same order or customer are being edited.
4.	More complete data structures.  You’ll notice that the customer file has only a customer name.  Customer addresses are added as part of the order process.  There should be customer editing form which defines this information so it can be inherited by each order.
5.	More drag and drop.  You should be able to copy customers and entire tables by dragging and dropping them.
6.	Etc.  The list is endless, including printing support, item pictures, A.I. front ends to second-guess whether customers really want what they’ve ordered.  Use your imagination.

How to Operate INVENT#$
INVENT consists of the following components, listed here in the order you will generally encounter them:
Main MDI Form
Database Table Browser
Customer Form
Parts Form
Order Browser
Order Entry Form
You can access each of these help pages by pressing F1 while that form is current within INVENT.
Overall Usage Notes
1.	You can close any form at any time without affecting the others.
2.	When you update data, it appears in red until you either (a) press F2 to force it to be updated, (b) move to another form or a new row, (c) press the ESC key to cancel the change and return to the prior values.
3.	You edit a cell by either (a) typing on top of it or (b) clicking on the cell while it is the current cell.
4.	Before you can drag a row, it must be the current row.  Thus, you must first select a row, by clicking, then hold down the mouse and drag the item.
5.	You can tell which drops are valid by looking at the cursor as you move it around on the screen.  The “no-drop” cursor shows you that you cannot drop the selected object at the current location.

Main MDI Form#$
The main MDI form is the “main window” of the INVENT application.  It contains menus as well as the status bar, where help information is displayed.  It is initially empty and you need to use the File/New or File/Open item to create a new database table.
Once tables are open, you can drag parts, customers, and orders onto the main MDI form in order to open them.

Database Table Browser#$
The database table browser contains a list of all tables in a given inventory database.  The database table browser is opened by choosing File/New or File/Open.  Inventory databases have the “.inv” extension, even though they are Access databases.  We use the “.inv” extension so we will recognize them easily.
The database name, type (Customers, Parts, or Orders) and date of last modification are shown.  You can double-click on a table, or drag it to the main form, to open it.  You can close the table browser at any time, even if one of its tables is opened.
While the table browser is displayed, you can add new tables by selecting Table/New, or delete a table by selecting Table/Delete.

Customer Form#$
The customer form displays customers.  You can add new customers by pressing the down-arrow, then typing a new customer name.  Dragging a customer into an Order Browser will create a new order for that customer.  You can’t delete customers right now.  Customer numbers are assigned by adding one to the last number.  The initial number will be 1000.  Change it if you like and other numbers will follow sequentially.
When you change data in a column, it appears in RED, indicating that it hasn’t been written yet.  To write the data immediately, press F2.  To discard the changes, press ESC.  The data you have entered will be automatically updated when you change to another row, or when you move to another form.

Parts Form#$
The parts form displays parts.  You can add new parts by pressing the down-arrow, then typing a new part name and price.  Dragging a part into an order entry form will add that part to the order (with a quantity of 1).  You can’t delete parts right now without deleting an entire part table.  Part numbers, like customer numbers, are assigned by adding one to the last number.  The initial number is 1000, and you are welcome to change it.  Other numbers will follow sequentially.
When you change data in a column, it appears in RED, indicating that it hasn’t been written yet.  To write the data immediately, press F2.  To discard the changes, press ESC.  The data you have entered will be automatically updated when you change to another row, or when you move to another form.

Order Browser#$
The order browser shows a list of orders and their current totals.  You can open an order browser by creating one in the Database Table Browser, then dragging it to open space in the MDI form.
To edit an order, you drag it to the MDI form as well.  When you return to an order browser, it redisplays the current row, in case the total has changed since the last time you visited it.  You can delete an order, and all of its items, by pressing the Delete key.
When you change data in a column, it appears in RED, indicating that it hasn’t been written yet.  To write the data immediately, press F2.  To discard the changes, press ESC.  The data you have entered will be automatically updated when you change to another row, or when you move to another form.

Order Entry Form#$
The order entry form contains details for an order, including name, address, line items, and totals.  You open an order entry form by dragging it from the order browser table.  You add line items by dragging them from a parts form.
You can change the quantity and price information for an order by typing new values in the cells.  The extended price will automatically recalculate.  When you change rows (or press F2), the record will be updated and the new subtotal will be shown.
When you change data in a column, it appears in RED, indicating that it hasn’t been written yet.  To write the data immediately, press F2.  To discard the changes, press ESC.  The data you have entered will be automatically updated when you change to another row, or when you move to another form.

Custom Controls Used by INVENT#$
The INVENT application uses the following custom controls:
THREED.VBX	Provided with Visual Basic professional.
CMDIALOG.VBX	Provided with Visual Basic Professional, and used for File/Open and File/New dialogs.
DRAGDROP.VBX	Used to detect File Manager drag and drop.  Written by Gary Wisniewski (CompuServe: 76130,2374), and available on the CompuServe MSBASIC forum Library 5.  Only the VBX is included with this project.  This is freeware and can be distributed and used without permission.  However, it is unsupported software.
TRUEDEMO.VBX	This is a demo version of TrueGrid, a database table browser.  The full demo package is available on CompuServe in the MSBASIC forum Library 6 (VBWin/3rd Party).  It is a fully-functional copy of the TrueGrid database table product, but can be used only at design time.
The Plug for TrueGrid
During the presentation, and througout the demo development, the focus has (hopefully) been on useful application techniques rather than specific features of our product.  However, you can get more information about TrueGrid, which is both inexpensive (only $69 right now) and easy-to-use, by calling Apex.  Our number is 1-800-858-APEX (or 1-412-681-4343).  You can reach us by FAX at 1-412-681-4384.
We hope you enjoyed the VBITS presentation and the included samples.